﻿using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Media;

namespace Gamev1
{
    class GameStateManager
    {
        #region GameState enum
        public enum GameState
        {
            MainMenu,
            Options,
            Playing,
            Restart,
            GameOver,
            LevelWon,
            ChooseLevel,
            ChooseCharacter,
            Resume,
            Pause,
            ChooseLevelCharacter
        }
        #endregion

        #region Fields
        private GameState currentGameState;
        private Button playButton,
                       exitButton,
                       helpButton,
                       backButton,
                       unlockButton,
                       nextlevelButton,
                       leveleenButton,
                       leveltweeButton,
                       leveldrieButton,
                       resumeButton,
                       restartButton,
                       characterOneButton,
                       characterTwoButton,
                       characterThreeButton,
                       controlOptions,
                       mainMenuButton,
                       startGameButton,
                       character_1Button,
                       character_2Button,
                       character_3Button,
                       level_1Button,
                       level_2Button,
                       level_3Button,
                       level_2ButtonLocked,
                       level_3ButtonLocked;

        private Game1 game;
        private Level level;
        private GameState previousGameState;
        private Texture2D mainMenuBackgroundTexture,
                          controlsBackgroundTexture,
                          characterLevelMenuBackgroundTexture;
        private int selectedCharacter = 1;
        private int selectedLevel = 1;
        private SpriteFont font;
        MouseState currentMouseState;
        private Song song;
        private bool[] magNaarVolgendLevel = new bool[2];
        #endregion

        public GameStateManager(Game1 game)
        {
            this.game = game;
            currentGameState = GameState.MainMenu;
            initialize();
        }

        private void drawMainMenu(SpriteBatch spriteBatch)
        {
            DrawScenery(spriteBatch, mainMenuBackgroundTexture);
            playButton.Draw(spriteBatch);
            exitButton.Draw(spriteBatch);
            helpButton.Draw(spriteBatch);
        }

        private void drawOptions(SpriteBatch spriteBatch)
        {
            DrawScenery(spriteBatch, controlsBackgroundTexture);
            controlOptions.Draw(spriteBatch);
            backButton.Draw(spriteBatch);
        }

        private void drawPause(SpriteBatch spriteBatch)
        {
            DrawScenery(spriteBatch, controlsBackgroundTexture);
            resumeButton.Draw(spriteBatch);
            restartButton.Draw(spriteBatch);
            helpButton.Draw(spriteBatch);
            mainMenuButton.Draw(spriteBatch);
        }

        private void drawGameOver(SpriteBatch spriteBatch)
        {
            DrawScenery(spriteBatch, controlsBackgroundTexture);
            spriteBatch.DrawString(font, "Score " + level.character.Score, new Vector2(mainMenuButton.Position.X - 50, mainMenuButton.Position.Y - 100), Color.Red);
            restartButton.Draw(spriteBatch);
            mainMenuButton.Draw(spriteBatch);
            helpButton.Draw(spriteBatch);
        }

        private void drawChooseLevelCharacter(SpriteBatch spriteBatch)
        {
            DrawScenery(spriteBatch, characterLevelMenuBackgroundTexture);
            character_1Button.Draw(spriteBatch);
            character_2Button.Draw(spriteBatch);
            character_3Button.Draw(spriteBatch);
            backButton.Draw(spriteBatch);
            startGameButton.Draw(spriteBatch);
            level_1Button.Draw(spriteBatch);
            if (magNaarVolgendLevel[0])
            {
                level_2Button.Draw(spriteBatch);
            }
            else
            {
                level_2ButtonLocked.Draw(spriteBatch);
            }
            if (magNaarVolgendLevel[1])
            {
                level_3Button.Draw(spriteBatch);
            }
            else
            {
                level_3ButtonLocked.Draw(spriteBatch);
            }
            unlockButton.Draw(spriteBatch);
            if (selectedCharacter == 1)
            {
                characterOneButton.Draw(spriteBatch);
            }
            else if (selectedCharacter == 2)
            {
                characterTwoButton.Draw(spriteBatch);
            }
            else if (selectedCharacter == 3)
            {
                characterThreeButton.Draw(spriteBatch);
            }
            if (selectedLevel == 1)
            {
                leveleenButton.Draw(spriteBatch);
            }
            else if (selectedLevel == 2)
            {
                leveltweeButton.Draw(spriteBatch);
            }
            else if (selectedLevel == 3)
            {
                leveldrieButton.Draw(spriteBatch);
            }
        }
        public void drawlevelWon(SpriteBatch spriteBatch)
        {
            DrawScenery(spriteBatch, controlsBackgroundTexture);
            spriteBatch.DrawString(font, "Score " + level.character.Score, new Vector2(nextlevelButton.Position.X + 150, nextlevelButton.Position.Y + 100), Color.Black);
            mainMenuButton.Draw(spriteBatch);
            restartButton.Draw(spriteBatch);
            if (selectedLevel == 1 || selectedLevel == 2)
            {
                nextlevelButton.Draw(spriteBatch);
            }
        }

        #region Update & Draw
        public void Draw(SpriteBatch spriteBatch)
        {
            switch (currentGameState)
            {
                case GameState.MainMenu:
                    drawMainMenu(spriteBatch);
                    break;
                case GameState.Playing:
                    level.draw(spriteBatch);
                    break;
                case GameState.Options:
                    drawOptions(spriteBatch);
                    break;
                case GameState.Pause:
                    drawPause(spriteBatch);
                    break;
                case GameState.GameOver:
                    drawGameOver(spriteBatch);
                    break;
                case GameState.ChooseLevelCharacter:
                    drawChooseLevelCharacter(spriteBatch);
                    break;
                case GameState.LevelWon:
                    drawlevelWon(spriteBatch);
                    break;
            }
        }

        public void Update(GameTime gameTime)
        {
            currentMouseState = Mouse.GetState();
            HandleMouseInput(gameTime);

            if (currentGameState == GameState.Playing)
            {
                if (MediaPlayer.State != MediaState.Playing)
                {
                    MediaPlayer.Play(song);
                }
            }
            else
            {
                MediaPlayer.Stop();
            }
        }
        #endregion

        #region Initialize & Load
        public void initialize()
        {
            playButton = new Button();
            exitButton = new Button();
            helpButton = new Button();
            backButton = new Button();
            leveleenButton = new Button();
            leveltweeButton = new Button();
            leveldrieButton = new Button();
            restartButton = new Button();
            resumeButton = new Button();
            characterOneButton = new Button();
            characterTwoButton = new Button();
            characterThreeButton = new Button();
            controlOptions = new Button();
            mainMenuButton = new Button();
            nextlevelButton = new Button();
            unlockButton = new Button();
            //testing...
            startGameButton = new Button();
            character_1Button = new Button();
            character_2Button = new Button();
            character_3Button = new Button();

            level_1Button = new Button();
            level_2Button = new Button();
            level_3Button = new Button();

            level_2ButtonLocked = new Button();
            level_3ButtonLocked = new Button();
        }

        public void loadContent(ContentManager contentManager)
        {
            mainMenuBackgroundTexture = contentManager.Load<Texture2D>("Background/MainMenuAchtergrond");
            controlsBackgroundTexture = contentManager.Load<Texture2D>("Background/ControlsAchtergrond");
            characterLevelMenuBackgroundTexture = contentManager.Load<Texture2D>("Background/characterLevelMenu");

            playButton.Texture = contentManager.Load<Texture2D>("Buttons/StartButton");
            exitButton.Texture = contentManager.Load<Texture2D>("Buttons/ExitButton");
            helpButton.Texture = contentManager.Load<Texture2D>("Buttons/ControlsButton");
            backButton.Texture = contentManager.Load<Texture2D>("Buttons/BackButton");
            nextlevelButton.Texture = contentManager.Load<Texture2D>("Buttons/NextLevelButton");
            restartButton.Texture = contentManager.Load<Texture2D>("Buttons/RestartButton");
            resumeButton.Texture = contentManager.Load<Texture2D>("Buttons/ResumeButton");
            mainMenuButton.Texture = contentManager.Load<Texture2D>("Buttons/MainMenuButton");
            unlockButton.Texture = contentManager.Load<Texture2D>("Buttons/UnlockButton");
            controlOptions.Texture = contentManager.Load<Texture2D>("Controls/controlsOptions");

            characterOneButton.Texture = contentManager.Load<Texture2D>("Buttons/character_1_groot");
            characterTwoButton.Texture = contentManager.Load<Texture2D>("Buttons/character_2_groot");
            characterThreeButton.Texture = contentManager.Load<Texture2D>("Buttons/character_3_groot");

            startGameButton.Texture = contentManager.Load<Texture2D>("Buttons/PlayButton");
            character_1Button.Texture = contentManager.Load<Texture2D>("Buttons/character_1_small");
            character_2Button.Texture = contentManager.Load<Texture2D>("Buttons/character_2_small");
            character_3Button.Texture = contentManager.Load<Texture2D>("Buttons/character_3_small");

            level_1Button.Texture = contentManager.Load<Texture2D>("Buttons/Level_1_small");
            level_2Button.Texture = contentManager.Load<Texture2D>("Buttons/Level_2_small");
            level_3Button.Texture = contentManager.Load<Texture2D>("Buttons/Level_3_small");

            leveleenButton.Texture = contentManager.Load<Texture2D>("Buttons/Level_1_small");
            leveltweeButton.Texture = contentManager.Load<Texture2D>("Buttons/Level_2_small");
            leveldrieButton.Texture = contentManager.Load<Texture2D>("Buttons/Level_3_small");

            level_2ButtonLocked.Texture = contentManager.Load<Texture2D>("Buttons/Level_2_small_lock");
            level_3ButtonLocked.Texture = contentManager.Load<Texture2D>("Buttons/Level_3_small_lock");

            //fonts
            font = contentManager.Load<SpriteFont>("score");

            //audio's
            song = contentManager.Load<Song>("song2");
            MediaPlayer.IsRepeating = true;
        }

        public void setContentPositions()
        {
            playButton.Position = new Vector2(Game1.screenWidth / 2 - playButton.Texture.Width / 2, 193);
            helpButton.Position = new Vector2(playButton.Position.X, playButton.Position.Y + 120);
            exitButton.Position = new Vector2(helpButton.Position.X, helpButton.Position.Y + 120);
            backButton.Position = new Vector2(35, Game1.screenHeight - backButton.Texture.Height - 45);

            unlockButton.Position = new Vector2(Game1.screenWidth - unlockButton.Texture.Width - 22, 15);

            controlOptions.Position = new Vector2((Game1.screenWidth - controlOptions.Texture.Width) / 2, 25);
            mainMenuButton.Position = new Vector2(helpButton.Position.X, helpButton.Position.Y - helpButton.Texture.Height - 30);
            restartButton.Position = new Vector2(helpButton.Position.X, mainMenuButton.Position.Y - restartButton.Texture.Height - 30);
            resumeButton.Position = new Vector2(helpButton.Position.X, helpButton.Position.Y + resumeButton.Texture.Height + 40);
            nextlevelButton.Position = new Vector2(mainMenuButton.Position.X, mainMenuButton.Position.Y + nextlevelButton.Texture.Height + 40);

            startGameButton.Position = new Vector2(Game1.screenWidth / 2 + 507, Game1.screenHeight - backButton.Texture.Height - 45);
            //kleine character plaatjes
            int screenCenter = Game1.screenWidth / 2;
            character_1Button.Position = new Vector2(screenCenter - 520, 152);
            character_2Button.Position = new Vector2(character_1Button.Position.X + character_2Button.Texture.Width + 33, character_1Button.Position.Y);
            character_3Button.Position = new Vector2(character_2Button.Position.X + character_3Button.Texture.Width + 33, character_1Button.Position.Y);
            //grote character plaatjes
            characterOneButton.Position = new Vector2(character_3Button.Position.X, character_1Button.Position.Y + 175);
            characterTwoButton.Position = characterOneButton.Position;
            characterThreeButton.Position = characterOneButton.Position;
            //kleine level plaatjes
            level_1Button.Position = new Vector2(screenCenter + 170, 152);
            level_2Button.Position = new Vector2(level_1Button.Position.X + level_2Button.Texture.Width + 33, level_1Button.Position.Y);
            level_3Button.Position = new Vector2(level_2Button.Position.X + level_3Button.Texture.Width + 33, level_1Button.Position.Y);

            level_2ButtonLocked.Position = new Vector2(level_2Button.Position.X, level_2Button.Position.Y - 10);
            level_3ButtonLocked.Position = new Vector2(level_3Button.Position.X, level_3Button.Position.Y - 10);

            //grote level plaatjes
            leveleenButton.Position = new Vector2(level_1Button.Position.X, level_1Button.Position.Y + 215);
            leveltweeButton.Position = leveleenButton.Position;
            leveldrieButton.Position = leveleenButton.Position;
        }
        #endregion

        #region Input

        private void updateChooseLevelCharacter()
        {
            if (backButton.isClicked)
            {
                currentGameState = GameState.MainMenu;
            }
            else if (startGameButton.isClicked)
            {
                currentGameState = GameState.Playing;
                level = new Level(game, selectedLevel, selectedCharacter);
            }
            else if (character_1Button.isClicked)
            {
                selectedCharacter = 1;
            }
            else if (character_2Button.isClicked)
            {
                selectedCharacter = 2;
            }
            else if (character_3Button.isClicked)
            {
                selectedCharacter = 3;
            }
            else if (level_1Button.isClicked)
            {
                selectedLevel = 1;
            }
            else if (level_2Button.isClicked && magNaarVolgendLevel[0])
            {
                selectedLevel = 2;
            }
            else if (level_3Button.isClicked && magNaarVolgendLevel[1])
            {
                selectedLevel = 3;
            }
            else if (unlockButton.isClicked)
            {
                magNaarVolgendLevel[0] = true;
                magNaarVolgendLevel[1] = true;
            }
            startGameButton.Update(currentMouseState);
            character_1Button.Update(currentMouseState);
            character_2Button.Update(currentMouseState);
            character_3Button.Update(currentMouseState);
            level_1Button.Update(currentMouseState);
            level_2Button.Update(currentMouseState);
            level_3Button.Update(currentMouseState);
            backButton.Update(currentMouseState);
            unlockButton.Update(currentMouseState);
        }

        private void updateMainMenu()
        {
            if (playButton.isClicked)
            {
                currentGameState = GameState.ChooseLevelCharacter;
            }
            else if (exitButton.isClicked)
            {
                game.Exit();
            }
            else if (helpButton.isClicked)
            {
                previousGameState = currentGameState;
                currentGameState = GameState.Options;
            }
            playButton.Update(currentMouseState);
            exitButton.Update(currentMouseState);
            helpButton.Update(currentMouseState);
        }

        private void updatePlaying(GameTime gameTime)
        {
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            {
                currentGameState = GameState.Pause;
            }
            else if (level.isGameOver)
            {
                currentGameState = GameState.GameOver;
            }
            else if (level.hasWonGame)
            {
                if (selectedLevel == 3)
                {
                    currentGameState = GameState.LevelWon;
                }
                else
                {
                    magNaarVolgendLevel[selectedLevel - 1] = true;
                    currentGameState = GameState.LevelWon;
                }
            }
            else
            {
                level.update(gameTime);
            }
        }

        private void updateOptions()
        {
            if (backButton.isClicked)
            {
                if (previousGameState == GameState.Pause)
                {
                    currentGameState = GameState.Pause;
                }
                else if (previousGameState == GameState.MainMenu)
                {
                    currentGameState = GameState.MainMenu;
                }
                else if (previousGameState == GameState.GameOver)
                {
                    currentGameState = GameState.GameOver;
                }
            }
            backButton.Update(currentMouseState);
        }

        private void updatePause()
        {
            if (resumeButton.isClicked)
            {
                currentGameState = GameState.Playing;
            }
            else if (helpButton.isClicked)
            {
                previousGameState = currentGameState;
                currentGameState = GameState.Options;
            }
            else if (restartButton.isClicked)
            {
                currentGameState = GameState.Playing;
                level = new Level(game, selectedLevel, selectedCharacter);
            }
            else if (mainMenuButton.isClicked)
            {
                currentGameState = GameState.MainMenu;
            }
            helpButton.Update(currentMouseState);
            restartButton.Update(currentMouseState);
            resumeButton.Update(currentMouseState);
            mainMenuButton.Update(currentMouseState);
        }

        private void updateGameOver()
        {
            if (mainMenuButton.isClicked)
            {
                currentGameState = GameState.MainMenu;
            }
            else if (restartButton.isClicked)
            {
                currentGameState = GameState.Playing;
                level = new Level(game, selectedLevel, selectedCharacter);
            }
            else if (helpButton.isClicked)
            {
                currentGameState = GameState.Options;
                previousGameState = GameState.GameOver;
            }
            mainMenuButton.Update(currentMouseState);
            restartButton.Update(currentMouseState);
            helpButton.Update(currentMouseState);
        }
        private void updateLevelWon()
        {
            if (mainMenuButton.isClicked)
            {
                currentGameState = GameState.MainMenu;
            }
            else if (restartButton.isClicked)
            {
                currentGameState = GameState.Playing;
                level = new Level(game, selectedLevel, selectedCharacter);
            }
            else if (nextlevelButton.isClicked)
            {
                selectedLevel += 1;
                currentGameState = GameState.Playing;
                level = new Level(game, selectedLevel, selectedCharacter);
            }
            mainMenuButton.Update(currentMouseState);
            restartButton.Update(currentMouseState);
            nextlevelButton.Update(currentMouseState);
        }

        private void HandleMouseInput(GameTime gameTime)
        {
            switch (currentGameState)
            {
                case GameState.MainMenu:
                    updateMainMenu();
                    break;
                case GameState.Playing:
                    updatePlaying(gameTime);
                    break;
                case GameState.Options:
                    updateOptions();
                    break;
                case GameState.Pause:
                    updatePause();
                    break;
                case GameState.GameOver:
                    updateGameOver();
                    break;
                case GameState.ChooseLevelCharacter:
                    updateChooseLevelCharacter();
                    break;
                case GameState.LevelWon:
                    updateLevelWon();
                    break;
            }
        }

        #endregion

        #region Getters & setters
        public GameState CurrentGameState
        {
            get { return currentGameState; }
        }

        #endregion


        private void DrawScenery(SpriteBatch spriteBatch, Texture2D achtergrondTexture)
        {
            Rectangle screenRectangle = new Rectangle(0, 0, Game1.screenWidth, Game1.screenHeight);
            spriteBatch.Draw(achtergrondTexture, screenRectangle, Color.White);
        }
    }

}
